feat(providers): implement Azure OpenAI provider with DIAL compatibility#365
feat(providers): implement Azure OpenAI provider with DIAL compatibility#365Ratgor wants to merge 2 commits into
Conversation
…ity and payload sanitization Details: - Add Azure OpenAI provider template and setup steps; - Implement comprehensive payload sanitization for DIAL endpoints to prevent schema errors; - Refine model family detection for vendor-prefixed IDs; - General cleanup and standards validation.
8nevil8
left a comment
There was a problem hiding this comment.
Code Review — feat(providers): Azure OpenAI + DIAL compatibility
Decision: REQUEST CHANGES
The core architecture is solid — per-deployment provider entries, api-key header injection, Claude-specific beforeRun hook disabling prompt caching and thinking, and the DIAL sanitizer plugin are all well-designed and well-documented. The blocking issues are a CI gate failure from test fixture strings, a UX bug (Russian-language string in English CLI output), and several logging-policy violations.
CR-001 — CRITICAL: Test fixture API key values trigger Gitleaks — CI is blocked
File: src/providers/plugins/azure-openai/__tests__/azure-openai.template.test.ts lines 20, 22, 24
Gitleaks generic-api-key rule matched 3 times on the string 'test-api-key-1234567890' assigned to AZURE_OPENAI_API_KEY, CODEMIE_API_KEY, and ANTHROPIC_AUTH_TOKEN in makeEnv(). The Secrets Detection CI gate fails, which causes Build and Test to skip — no test execution evidence exists for this PR.
Fix: Replace with a placeholder that won't match entropy rules, e.g. 'PLACEHOLDER-KEY-FOR-TESTING-ONLY' or 'test-key-xxxxx'. Check for the same pattern in any other test files added in this PR.
CR-002 — MAJOR: dial-model-integrity.ts uses console.log/console.error throughout
File: src/utils/dial-model-integrity.ts
The entire file uses console.log and console.error for all output. Per development-practices.md and code-quality.md, production code must use logger.* (debug/warn/error) — console.log is explicitly prohibited for diagnostics. The pre-commit checklist item is "No console.log() left in code".
Fix: Replace internal diagnostic calls with logger.info/logger.warn/logger.error. User-facing table output (the summary printed to stdout) can remain as console.log, but non-diagnostic messages must go through the logger.
CR-003 — MAJOR: Russian-language string in --test-dial CLI output + console.log in CLI command
File: src/cli/commands/doctor/index.ts lines ~1525–1528
The --test-dial error branch emits a mixed Russian/English message via console.log:
dial integration test: active profile provider не DIAL/azure-openai. Выберите профиль DIAL через codemie profile switch или setup.
This will render as unreadable text for all non-Russian users. Additionally, console.log is used in a CLI command instead of the project's logger or chalk-formatted output.
Fix: Replace with English: 'The active profile provider is not DIAL/azure-openai. Switch to a DIAL profile via "codemie profile switch" or run "codemie setup".' Move to logger.warn or a proper CLI error output pattern.
CR-004 — MAJOR: Bare Error thrown in auto-retry-sanitizer.ts
File: src/agents/plugins/azure-dial-sanitizer/auto-retry-sanitizer.ts line 315
requestWithSanitizerRetry throws new Error('[DIAL Retry] ...'). Per development-practices.md, project code must use specific error classes from src/utils/errors.ts (e.g. ToolExecutionError), not bare Error.
Fix:
import { ToolExecutionError } from '../../../utils/errors.js';
// ...
throw new ToolExecutionError(`[DIAL Retry] Request failed after sanitize retry: ${err2?.message || err2}`);CR-005 — MAJOR: console.error added in setup.ts model-fetch catch block
File: src/cli/commands/setup.ts line ~560
The new console.error(chalk.red('Failed to fetch models'), error) bypasses the logger (no log-level control, no file output, raw error object may contain sensitive request details).
Fix: Replace with logger.warn('[setup] Could not fetch models', { error: error instanceof Error ? error.message : String(error) }) to match the surrounding code and the project logging standard.
CR-006 — MAJOR: Indentation defect in buildOpenCodeConfig() in codemie-code.plugin.ts
File: src/agents/plugins/codemie-code.plugin.ts lines ~776–782
The baseEnabledProviders and enabledProviders declarations and their if/else block are indented at column 0 inside the function body, while the surrounding code uses 2-space indentation. This will fail the lint-staged ESLint run.
Fix: Re-indent the block to match the 2-space indentation of the enclosing function body.
CR-007 — MAJOR: Exported function in auto-retry-sanitizer.ts missing JSDoc
File: src/agents/plugins/azure-dial-sanitizer/auto-retry-sanitizer.ts line ~298
requestWithSanitizerRetry is an exported public API using any-typed parameters. Per code-quality.md, all exported functions need explicit return types (present but typed Promise<any>) and JSDoc on all public APIs — especially when any is used, which the guide requires to be documented with a rationale.
Fix: Add a JSDoc block explaining the any parameter types and what the function guarantees.
CR-008 — MINOR: Source-level AzureDial / azure-dial-sanitizer naming is inconsistent with the provider name azure-openai
Files:
src/agents/plugins/azure-dial-sanitizer/(directory)azure-dial-sanitizer-source.ts:AzureDialSanitizerPlugin,sanitizeAzureDialPayload,AZURE_DIAL_SANITIZER_PLUGIN_SOURCEinject-sanitizer.ts:getAzureDialSanitizerPluginUrl,cleanupAzureDialSanitizerPlugin
Every other artifact in this PR uses AzureOpenAI naming (AzureOpenAITemplate, AzureOpenAIHealthCheck, AzureOpenAIModelProxy, provider name 'azure-openai'). The DIAL suffix leaks an EPAM-specific implementation detail into public source identifiers; the sanitizer is equally necessary for plain Azure OpenAI endpoints, not only DIAL gateways.
Important distinction — what must stay as azure-dial-:
The runtime OpenCode provider key prefix (azure-dial-{modelId}, built by buildAzureOpenAIProviders()) and the in-plugin guard pid.startsWith("azure-dial-") are intentionally coupled and must remain in sync. That is an internal OpenCode config namespace that users never see, and the existing comment in buildAzureOpenAIProviders() explains the convention clearly — no change needed there.
What should be renamed (source-level identifiers only):
| Current | Suggested |
|---|---|
azure-dial-sanitizer/ (directory) |
azure-openai-sanitizer/ |
AzureDialSanitizerPlugin |
AzureOpenAISanitizerPlugin |
sanitizeAzureDialPayload |
sanitizeAzureOpenAIPayload |
AZURE_DIAL_SANITIZER_PLUGIN_SOURCE |
AZURE_OPENAI_SANITIZER_PLUGIN_SOURCE |
getAzureDialSanitizerPluginUrl |
getAzureOpenAISanitizerPluginUrl |
cleanupAzureDialSanitizerPlugin |
cleanupAzureOpenAISanitizerPlugin |
This keeps source-level naming consistent with the registered provider name and removes the EPAM DIAL-specific term from the public module API. The runtime azure-dial-* key convention is a separate concern and stays unchanged.
|
[AUTO_CLOSE_WARNING] ⏰ This pull request is older than 14 days and will be automatically closed in 16 more days (when it reaches 30 days old)! To maintain this PR, either convert it to Draft or complete your changes and merge. |
Summary
Implements the Azure OpenAI provider with specific compatibility for the DIAL gateway, including payload sanitization to prevent API errors.
Changes
Test Plan
Checklist